`include "PRV564Config.v"
`include "PRV564Define.v"
//////////////////////////////////////////////////////////////////////////////////////////////////
//  Date    : 2021                                                                              //
//  Author  : Jack.Pan                                                                          //
//  Desc    : Virtual TCM for PRV564 processor YSYX210152_Simulation                                       //
//  Version : 0.0(Original Verision)                                                            //
//////////////////////////////////////////////////////////////////////////////////////////////////
module Virtual_TCM(
    input wire              VTCMi_CLK,
    input wire              VTCMi_ARST,
    input wire              VTCMi_Flush,
    //---------------From Last Stage----------
    input wire              PIP_VTCMi_MSC_valid,
    input wire [7:0]        PIP_VTCMi_opcode,
    input wire [3:0]        PIP_VTCMi_opsize,
    input wire              PIP_VTCMi_MSC_InstPageFlt,
    input wire [1:0]        PIP_VTCMi_INFO_priv,
    input wire [`XLEN-1:0]  PIP_VTCMi_INFO_pc,
    input wire [`XLEN-1:0]  PIP_VTCMi_DATA_PA,
    input wire [`XLEN-1:0]  PIP_VTCMi_DATA_ds1,
    output reg              PIP_VTCMo_FC_ready,
    //------------To next stage---------------
    output reg              PIP_VTCMo_MSC_valid,
    output reg              PIP_VTCMo_MSC_InstPageFlt,
    output reg              PIP_VTCMo_MSC_InstAccFlt,
    output reg              PIP_VTCMo_MSC_InstAddrMis,   
    output reg [`XLEN-1:0]  PIP_VTCMo_DATA_data,
    output reg [`XLEN-1:0]  PIP_VTCMo_INFO_pc,
    output reg [1:0]        PIP_VTCMo_INFO_priv,
    input wire              PIP_VTCMi_FC_ready

);
    wire        Valid;
    reg [63:0]  BRAM[255:0];      //256 Word * 8Byte RAM
assign Valid = !VTCMi_Flush & PIP_VTCMi_MSC_valid;
initial
begin 
	$readmemh("Program.txt",BRAM);
end
always@(posedge VTCMi_CLK or posedge VTCMi_ARST)begin
    if(VTCMi_ARST)begin
        PIP_VTCMo_MSC_valid         <= 1'b0;
        PIP_VTCMo_MSC_InstPageFlt   <= 1'b0;
        PIP_VTCMo_DATA_data         <= 64'h0;
        PIP_VTCMo_INFO_pc           <= 64'h0;
        PIP_VTCMo_INFO_priv         <= 2'b11;
    end
    else if(PIP_VTCMo_MSC_valid & !PIP_VTCMi_FC_ready)begin
        PIP_VTCMo_MSC_valid         <= PIP_VTCMo_MSC_valid;
        PIP_VTCMo_MSC_InstPageFlt   <= PIP_VTCMo_MSC_InstPageFlt;
        PIP_VTCMo_DATA_data         <= PIP_VTCMo_DATA_data;
        PIP_VTCMo_INFO_pc           <= PIP_VTCMo_INFO_pc;
        PIP_VTCMo_INFO_priv         <= PIP_VTCMo_INFO_priv;
    end
    else begin
        PIP_VTCMo_MSC_valid         <= Valid;
        PIP_VTCMo_MSC_InstPageFlt   <= PIP_VTCMi_MSC_InstPageFlt;
        PIP_VTCMo_DATA_data         <= BRAM[PIP_VTCMi_DATA_PA[63:3]];
        PIP_VTCMo_INFO_pc           <= PIP_VTCMi_INFO_pc;
        PIP_VTCMo_INFO_priv         <= PIP_VTCMi_INFO_priv;
    end
end

//---------------ready output-----------------
always@(*)begin
    if(PIP_VTCMo_MSC_valid)begin
        if(!PIP_VTCMi_FC_ready)begin
            PIP_VTCMo_FC_ready <= 1'b0;
        end
        else begin
            PIP_VTCMo_FC_ready <= 1'b1;
        end
    end
    else begin
        PIP_VTCMo_FC_ready <= 1'b1;
    end
end

endmodule